
================================================================================================
CROWN PRODUCT REFERENCE RESOURCE (PRR) API
Copyright © 2025 – Crown Equipment Corporation
Version 1.0 – October 2025
================================================================================================

------------------------------------------------------------------------------------------------
REGARDING THIS DEMO:
------------------------------------------------------------------------------------------------

1. To verify connection with Crown API, upload the 'crown-API-Examples' folder to the dealer
domain that will support the API.

2. Once uploaded, access each example to confirm that the 'Single Product' Endpoint and the
'Region' Endpoint are displaying data correctly.

3. If you experience any CORS related issues, please contact Crown so that your secure
connection can be confirmed with Crown's IT Department.

This README file documents the provided POC code, assuming its purpose is to fetch and display a product details for a product category:

------------------------------------------------------------------------------------------------
PRODUCT DETAIL PAGE
------------------------------------------------------------------------------------------------

This JavaScript code is designed to fetch product data from a JSON API and dynamically render this data into the DOM. This script leverages the Fetch API for asynchronous HTTP requests and ES6 features, including template literals and array methods, to construct the HTML.

------------------------------------------------------------------------------------------------
PREREQUISITES
------------------------------------------------------------------------------------------------

This script assumes the existence of certain HTML elements, especially a container element with ID `data-container`, where the product information will be rendered.

------------------------------------------------------------------------------------------------
HOW IT WORKS
------------------------------------------------------------------------------------------------
SETUP AND INITIALIZATION
------------------------------------------------------------------------------------------------

1. **Data Path Retrieval**: The script retrieves the API endpoint from a `data-path` attribute on an HTML element with the ID `product-detail-wrapper`.

   ```javascript
   const jsonURL = document.querySelector("#product-detail-wrapper").dataset.path;
   ```

2. **Define API URL**: Stores the fetched API endpoint into a constant `url`.

   ```javascript
   const url = jsonURL;
   ```
------------------------------------------------------------------------------------------------
FETCHING THE DATA
------------------------------------------------------------------------------------------------

- **Fetch API**: Initiates a GET request to the endpoint defined in `url` and parses the response as JSON.

  ```javascript
  fetch(url).then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok ' + response.statusText);
      }
      return response.json();
    }).then(data => {
      displayData(data);
    }).catch(error => {
      document.getElementById('data-container').innerHTML = '<p>Error loading data. Please try again later.</p>';
      console.error('Fetch error:', error);
    });
  ```

  - **Error Handling**: Ensures proper handling of unsuccessful requests with error messages logged to the console and displayed to the user.

------------------------------------------------------------------------------------------------
RENDERING THE DATA
------------------------------------------------------------------------------------------------

- **`renderItem(item)` Function**: Builds HTML content using the provided JSON data.

- **`displayData(data)` Function**: Inserts HTML content into the page. This is accomplished with a for loop that grabs and renders the specified products matching the forklift category.

  ```javascript
  function renderItem(item) {
    //const item = data.data.baseProductByPath.item;

    // Build lists for product details
    const productDetails = item.productDetails.map(detail => {
      return `<li><span>${detail.productDetailDisplayLabel}:</span> ${detail.productDetailFieldValue.plaintext}</li>`;
    }).join('');

    // Build applications list
    const applications = item.localizedProductFeature.applications.map(app => `<li>${app}</li>`).join('');

    // Build specifications
    const specifications = item.productSpecification.map(spec => {
      return `<li><span>${spec.specificationLabel}</span> ${spec.specifcationMeasureImperial} | ${spec.specifcationMeasureMetric}</li>`;
    }).join('');

    // Build resources links
    const resources = item.productResources.map(res => {
      return res.resourceLabel ? `<li><span>${res.resourceLabel}:</span> <a title="${res.resourceLabel}" href="${res.resourceLink ? res.resourceLink._publishUrl : '#'}">${res.resourceLink ? res.resourceLink._publishUrl : '#'}</a></li>` : '';
    }).join('');

    // Sort and group images by category, then build image HTML
    const sortedImages = [...item.productImages].sort((a, b) => a.imageCategory.localeCompare(b.imageCategory));

    const images = sortedImages.reduce((acc, imageGroup) => {
      const category = imageGroup.imageCategory;
      if (!acc[category]) {
        acc[category] = [];
      }
      acc[category].push(imageGroup);
      return acc;
    }, {});

    const imageHtml = Object.keys(images).map(category => {
      const variantsHtml = images[category].map(imageGroup => {
        const variantBlocks = imageGroup.imageVariants.map(variant => {
          return `
                <li><a href="${variant.imageLink}" title="${variant.imageLabel}" target="_blank">${variant.imageLabel} <i class="fas fa-link"></i></a></li>
              `;
        }).join('');
        return `<div class="product-image-group"><img src="${imageGroup.imageThumbnail}" alt="${imageGroup.imageCategory}" /><ul>${variantBlocks}</ul></div>`;
      }).join('');
      return `<div class="image-section"><h3>${category}</h3><div class="product-image-variants">${variantsHtml}</div>`;
    }).join('');

    // Construct final HTML template using template literals
    const template = `
      <div class="content">
        <h1>${item.productSeries.seriesId} Product Information</h1>
        <p>Last updated on: ${new Date(item.lastPublishedDate).toLocaleString()} <a href="#">Subscribe to receive email updates</a></p>
        <p> Here would lie the list of updates that were changed on the last revision date, this will allow the dealer to evaluate the information more quickly. Lorem Ipsum Lorem ipsum lorem ipsum lorem ipsum.</p>
        <div class="product-section">
          <h2>Product Details</h2>
          <ul>
            <li><span>Product Base Code:</span> ${item.productBaseCode}</li>
            <li><span>Series:</span> ${item.productSeries.seriesId}</li>
            <li><span>Category:</span> ${item.productSeries.productCategory}</li>
            ${productDetails}
          </ul>
        </div>
        <div class="product-section">
          <h2>Product Specifications & Applications</h2>
          <ul>
            <li><span>${item.localizedProductFeature.forkliftTypeDisplayLabel}:</span> ${item.localizedProductFeature.forkliftType}</li>
            <li><span>${item.localizedProductFeature.powerTypeDisplayLabel}:</span> ${item.localizedProductFeature.powerType}</li>
            <li><span>${item.localizedProductFeature.operatingPositionDisplayLabel}:</span> ${item.localizedProductFeature.operatingPosition}</li>
            <li><span>${item.localizedProductFeature.applicationsDisplayLabel}:</span>
            <ul>${applications}</ul>
            </li>
            <li><span>${item.localizedProductFeature.mastTypeDisplayLabel}:</span> ${item.localizedProductFeature.mastType.join(', ')}</li>
            ${specifications}
          </ul>
        </div>
        <div class="product-section">
          <h2>Resources</h2>
          <ul class="product-resources">
            ${resources}
          </ul>
        </div>
        <div class="product-section">
          <h2>Images</h2>
          <div class="product-images">
            ${imageHtml}
          </div>
        </div>
      </div>
    `;
    return template;
  }
  ```
```javascript
function displayData(data) {
  
  const items = data.data.baseProductList.items;
  // for loop goes through data and renders every item that passes the check.
  for (let i = 0; i < items.length; i++) {
    let item = items[i];    
    // if statement to check product category type
    if (item.localizedProductFeature.forkliftType == "Pallet") {
      template = renderItem(item);
      //constructs a new block of content for each product found in category. 
      document.getElementById('data-container').innerHTML += template;
    };
  };

}
```


  - **Product Details, Applications, and Specifications**: Utilizes `map` and other array methods to create HTML content for lists of details, applications, and specifications.
  - **Resources**: Generates clickable links to additional resources with titles.
  - **Images**: Sorts and groups images by category, then generates image blocks including clickable links.
  - **HTML Insertion**: The final HTML is inserted into the DOM element with ID `data-container`.

------------------------------------------------------------------------------------------------
USAGE
------------------------------------------------------------------------------------------------

1. Ensure you have a HTML element with a `data-path` attribute containing the API URL you wish to fetch data from.
2. Include a container with the ID `data-container` for rendering the fetched and formatted data.
3. Include Font Awesome or update/removes relevant icon references to avoid console errors if the library is not used.


------------------------------------------------------------------------------------------------
FURTHER RESOURCES
------------------------------------------------------------------------------------------------
Main Reference Site:
    https://www.crown.com/product-reference-resource/en-us.html

Demo Examples:
    https://media.crown.com/marketing/cfx/crown-API-Examples/

Support:
    Contact Crown's Support Center at 419-629-2311 ext. 1300

------------------------------------------------------------------------------------------------
Thank you for partnering with Crown.
By using the PRR API, your website will always display the most accurate and current
Crown product information available.
================================================================================================
